path = "/gpfs/hpchome/a72094/rocket/projects/chromatin_to_splicing/"
Warning message:
no function found corresponding to methods exports from ‘XVector’ for: ‘concatenateObjects’ 
library("dplyr")

Attaching package: ‘dplyr’

The following objects are masked from ‘package:GenomicRanges’:

    intersect, setdiff, union

The following object is masked from ‘package:GenomeInfoDb’:

    intersect

The following objects are masked from ‘package:IRanges’:

    collapse, desc, intersect, setdiff, slice, union

The following objects are masked from ‘package:S4Vectors’:

    first, intersect, rename, setdiff, setequal, union

The following objects are masked from ‘package:BiocGenerics’:

    combine, intersect, setdiff, union

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library("readr")
library("devtools")
library("rtracklayer")
library("wiggleplotr")
library("GenomicRanges")
library('Rsamtools')
Loading required package: Biostrings
Loading required package: XVector

Attaching package: ‘Biostrings’

The following object is masked from ‘package:base’:

    strsplit
library('tidyr')

Attaching package: ‘tidyr’

The following object is masked from ‘package:S4Vectors’:

    expand
load_all("/gpfs/rocket/home/a72094/projects/chromatin_to_splicing/seqUtils/")
Loading seqUtils

Splaissimise andmed

#geenid, millel leidub splaiss QTL
splicing = read.table(paste0(path, "tabix/txrevise.significant.contained.sorted.txt.gz"))
#r2 seotud splass ja ca lookuste paarid
ca_splicing = read.table(paste0(path, "results/rsquared08/cqn_contained_rsq.txt"))

Kromatiini avatuse andmed

Aluseks peavad olema kromatiini avatuse kühmud, millel leidub: 1. statistiliselt oluline caQTL 25872 2. caQTL on seotud splaiss QTL’ga

Alustuseks leian kõik kühmud, mis vastavad kriteeriumitele

ca_interesting_peaks = ca[which(ca$V8 %in% ca_splicing$V1),]
Error: object 'ca' not found

Geenid, mille splaissimine on R2 seotud kromatiini avatusega

interesting_genes = splicing[which(splicing$V10 %in% ca_splicing$V4),c("V1", "V2", "V3","V4","V10","V12","V19","V21")]
colnames(interesting_genes) = c("gene_id", "gene_chr","gene_start","gene_end","gene_snpid", "gene_snp_pos","gene_slope","gene_pvalue")
interesting_genes

Seon kromatiini kühmud ja geenid

interesting = dplyr::left_join(interesting_genes, ca_splicing, by = c("gene_snpid"="V4"))[1:9] %>% left_join(interesting_peaks, ., by=c('peak_snpid'='V1'))
Column `gene_snpid`/`V4` joining factors with different levels, coercing to character vectorColumn `peak_snpid`/`V1` joining factors with different levels, coercing to character vector
interesting = dplyr::select(interesting, -one_of('ctcf_chr','gene_chr', 'peak_snp_chr'))
Unknown columns: `ctcf_chr`
interesting$gene_id = substr(interesting$gene_id, 1, nchar("ENSG00000171735.contained")-10)
interesting
write.table(interesting, file = paste0(path, 'interesting.txt'), col.names = T, quote = F, row.names = F, append = F)
interesting = read.table(paste0(path, 'interesting.txt'), header = TRUE)
filtered = interesting[which(abs(interesting$peak_slope)>0.4 & abs(interesting$gene_slope)>0.4 & interesting$ca_pvalue<1e-4 & interesting$gene_pvalue<1e-4),]
filtered

ATAC

#proovid
ATAC_sample_metadata = read.table(paste0(path,'QC_measures/run_sample_accession_PhaseIII.txt'))
colnames(ATAC_sample_metadata) = c("sample_id", "genotype_id")
ATAC_sample_metadata["condition_name"] = rep("naive", dim(ATAC_sample_metadata)[1])
#genotüübid
vcf_file = readRDS(paste0(path, 'genotypes/Kumasaka_100_samples.merged.rds'))
ATAC_meta_df = read.table(paste0(path, 'ATAC_meta_df'), header = TRUE)
ATAC_peak_metadata = read.table(paste0(path,'ATAC_peak_metadata'), header = TRUE)
regions_df = unique(filtered[,c('peak_id', 'peak_chr','peak_start', 'peak_end','peak_snpid','gene_id', 'peak_chr','gene_start', 'gene_end','gene_snpid','gene_snp_pos')])
colnames(regions_df) = c('peak_id', 'peak_chr', 'peak_start', 'peak_end', 'peak_rs_id', 'gene_id', 'gene_chr', 'gene_start', 'gene_end', 'gene_rs_id', 'gene_pos')
regions_df
#rm(vcf_file,ATAC_counts)

RNA

RNA_sample_metadata = read.table("/gpfs/hpchome/a72094/hpc/datasets/controlled_access/SampleArcheology/studies/cleaned/GEUVADIS.tsv", header = TRUE)[,c("sample_id","genotype_id","condition")]
colnames(RNA_sample_metadata)[3] = "condition_name"
if (FALSE){
  # RNA seq lugemite arv used for calculating library size
  RNA_counts = read.table("/gpfs/hpchome/a72094/hpc/projects/RNAseq_pipeline/results/expression_matrices/featureCounts/GEUVADIS.tsv.gz", header = TRUE)
  RNA_meta_df = wiggleplotrConstructMetadata(RNA_counts, RNA_sample_metadata, "/gpfs/hpc/home/a72094/projects/RNAseq_pipeline/processed/GEUVADIS/bigwig", bigWig_suffix = ".str1.bw", condition_name_levels = c("naive"))
  rm(RNA_counts)
  saveRDS(RNA_meta_df, paste0(path, 'RNA_meta_df'))
}
RNA_meta_df = readRDS(paste0(path, 'RNA_meta_df'))
RNA_meta_df
regions_df = unique(filtered[,c('gene_id', 'peak_chr','gene_start', 'gene_end','gene_snpid','gene_snp_pos')])
colnames(regions_df) = c('gene_id', 'chr', 'start', 'end', 'rs_id', 'pos')
regions_df

geenide annotatsioonid ja transkriptide annotatsioonid

gtf_df <- as.data.frame(rtracklayer::import(paste0(path, 'genotypes/Homo_sapiens.GRCh38.96.chr.gtf.gz')))
  filtered_annotations = gtf_df[gtf_df$gene_id %in% regions_df$gene_id,]
  filtered_annotations

  rm(gtf_df)
  saveRDS(filtered_annotations, paste0(path, 'filtered_annotations'))
filtered_annotations = readRDS(paste0(path, 'filtered_annotations'))
filtered_annotations

Koik geeni eksonid GRanges objektidena

find_peak_annotations = function(region_coords, chr, RNA_peak_metadata){
  RNA_peak_annot = wiggleplotrExtractPeaks(region_coords, chrom = chr, RNA_peak_metadata)
  RNA_peak_annot$peak_annot$transcript_id='RNA'
  RNA_peak_annot$peak_annot$gene_id = 'RNA'
  RNA_peak_annot$peak_annot$gene_name = 'RNA-seq'
  names(RNA_peak_annot$peak_list) = 'RNA'
  return(RNA_peak_annot)
}

Leian vcf failist loigu, mis vastab uuritavale geenile

find_genotype = function(gene_id, region_coords){
  library(GenomicRanges)
  gene_range = GRanges(seqnames =filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'seqnames'], strand = c("*"), ranges = IRanges(start = region_coords[1], end = region_coords[2], names = gene_id))
  vcf_file = paste0(path, 'genotypes/GEUVADIS_GRCh38_filtered.vcf.gz')
  genotype = scanTabixDataFrame(vcf_file, gene_range, col_names = FALSE)[[1]]
  #saveRDS(genotype, paste0(path, 'genotype'))
  
  #zgrep -m 1 "#CHROM" GEUVADIS_GRCh38_filtered.vcf.gz > vcf_genotype_id
  #vim vcf_genotype_id delete #
  
  v = scan(paste0(path, '/genotypes/vcf_genotype_id'), character(), quote = "")
  #unlink(paste0(path, '/genotypes/vcf_genotype_id'))
  colnames(genotype) = v
  
  genotype[genotype=="0|0"]<-0
  genotype[genotype=="1|0"]<-1
  genotype[genotype=="0|1"]<-1
  genotype[genotype=="1|1"]<-2
  
  return(genotype)
}
find_track_data = function(genotype, chr, RNA_meta_df){
  # add colour group
  colour_group = genotype[which(genotype$CHROM==chr & genotype$POS==pos), ] %>% select(10:454) %>% gather(., key= colnames(.), value=.[1,])
  colnames(colour_group) = c('genotype_id', 'colour_group')
  
  RNA_track_data = dplyr::left_join(RNA_meta_df, colour_group, by='genotype_id') %>% dplyr::mutate(track_id = "RNA-seq")
  RNA_track_data[, 'colour_group'] = as.factor(RNA_track_data[, 'colour_group'])
  return(RNA_track_data)
}

ATAC joonised

joint_plotlist = list()

for (i in 1:dim(regions_df)[1]){
  ATAC_rs_id = regions_df[i, 'peak_rs_id']
  ATAC_region_coords=c(regions_df[i,'peak_start']-1000, regions_df[i,'peak_end']+1000)
  chr = regions_df[i,'peak_chr']
  ATAC_peak_annot = wiggleplotrExtractPeaks(region_coords, chrom = chr, ATAC_peak_metadata)
  
  # add colour group
  ATAC_colour_group = data.frame(genotype_id = names(vcf_file$genotypes[ATAC_rs_id,]), colour_group=vcf_file$genotypes[rs_id,])
  ATAC_track_data = dplyr::left_join(ATAC_meta_df, ATAC_colour_group, by='genotype_id') %>% dplyr::mutate(track_id = "ATAC-seq")
  ATAC_track_data[, 'colour_group'] = as.factor(ATAC_track_data[, 'colour_group'])
  
  ATAC_coverage = plotCoverage(exons = ATAC_peak_annot$peak_list, cdss = ATAC_peak_annot$peak_list, track_data = ATAC_track_data, rescale_introns = FALSE, 
                             transcript_annotations = ATAC_peak_annot$peak_annot, fill_palette = getGenotypePalette(),
                             connect_exons = FALSE, transcript_label = FALSE, plot_fraction = 0.1, heights = c(0.7,0.3), 
                             region_coords = ATAC_region_coords, return_subplots_list = TRUE, coverage_type = "line")
  
  
  joint_plot = cowplot::plot_grid(ATAC_coverage$coverage_plot, 
                                ATAC_coverage$tx_structure,
                                align = "v", ncol = 1, rel_heights = c(3,2))
  
  joint_plotlist[[i]] = joint_plot
  print(joint_plot)
  ggsave(paste0('/gpfs/hpchome/evelin95/plots/ca_splicing/',regions_df[i,'peak_id'],'.pdf'))
  
}

RNA joonised

library(ggplot2)
RNA_coverage_plotlist = list()
for (i in 1:dim(regions_df)[1]){
  rs_id = regions_df[i, 'rs_id']
  pos = regions_df[i, 'pos']
  gene_id = regions_df[i, 'gene_id']
  region_coords = c(filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'start'], filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'end'])
  chr = regions_df[i,'chr']
  
  RNA_peak_metadata = filtered_annotations[which(filtered_annotations$type=='exon' & filtered_annotations$gene_id==gene_id),c("seqnames", "start", "end", "strand")]
  colnames(RNA_peak_metadata)[1]='chr'
  
  genotype=find_genotype(gene_id, region_coords)
  
  RNA_peak_annot = find_peak_annotations(region_coords, chr, RNA_peak_metadata)
  RNA_track_data = find_track_data(genotype, chr, RNA_meta_df)
  
  RNA_coverage = plotCoverage(exons = RNA_peak_annot$peak_list, cdss = RNA_peak_annot$peak_list, track_data = RNA_track_data, rescale_introns = TRUE, 
                             transcript_annotations = RNA_peak_annot$peak_annot, fill_palette = getGenotypePalette(),
                             connect_exons = FALSE, transcript_label = FALSE, plot_fraction = 0.1, heights = c(0.7,0.3), 
                             region_coords = region_coords, return_subplots_list = TRUE, coverage_type = "line")
  
  
  RNA_coverage_plotlist[[i]] = RNA_coverage$coverage_plot
  print(RNA_coverage$coverage_plot)
  ggsave(paste0('/gpfs/hpchome/evelin95/plots/ca_splicing/',gene_id,'.pdf'))
}
Read 454 items
Column `genotype_id` joining factor and character vector, coercing into character vectorRead 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items

LS0tCnRpdGxlOiAiS3JvbWF0aWluaSBhdmF0dXNlIGphIHNwbGFpc3NpbWlzZSBzZW9zdGUgdmlzdWFsaXNlZXJpbWluZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnBhdGggPSAiL2dwZnMvaHBjaG9tZS9hNzIwOTQvcm9ja2V0L3Byb2plY3RzL2Nocm9tYXRpbl90b19zcGxpY2luZy8iCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgicmVhZHIiKQpsaWJyYXJ5KCJkZXZ0b29scyIpCmxpYnJhcnkoInJ0cmFja2xheWVyIikKbGlicmFyeSgid2lnZ2xlcGxvdHIiKQpsaWJyYXJ5KCJHZW5vbWljUmFuZ2VzIikKbGlicmFyeSgnUnNhbXRvb2xzJykKbGlicmFyeSgndGlkeXInKQpsb2FkX2FsbCgiL2dwZnMvcm9ja2V0L2hvbWUvYTcyMDk0L3Byb2plY3RzL2Nocm9tYXRpbl90b19zcGxpY2luZy9zZXFVdGlscy8iKQpgYGAKCgpTcGxhaXNzaW1pc2UgYW5kbWVkCmBgYHtyfQojZ2VlbmlkLCBtaWxsZWwgbGVpZHViIHNwbGFpc3MgUVRMCnNwbGljaW5nID0gcmVhZC50YWJsZShwYXN0ZTAocGF0aCwgInRhYml4L3R4cmV2aXNlLnNpZ25pZmljYW50LmNvbnRhaW5lZC5zb3J0ZWQudHh0Lmd6IikpCgojcjIgc2VvdHVkIHNwbGFzcyBqYSBjYSBsb29rdXN0ZSBwYWFyaWQKY2Ffc3BsaWNpbmcgPSByZWFkLnRhYmxlKHBhc3RlMChwYXRoLCAicmVzdWx0cy9yc3F1YXJlZDA4L2Nxbl9jb250YWluZWRfcnNxLnR4dCIpKQpgYGAKCktyb21hdGlpbmkgYXZhdHVzZSBhbmRtZWQKCkFsdXNla3MgcGVhdmFkIG9sZW1hIGtyb21hdGlpbmkgYXZhdHVzZSBrw7xobXVkLCBtaWxsZWwgbGVpZHViOgoxLiBzdGF0aXN0aWxpc2VsdCBvbHVsaW5lIGNhUVRMIDI1ODcyCjIuIGNhUVRMIG9uIHNlb3R1ZCBzcGxhaXNzIFFUTCdnYSAKCgpBbHVzdHVzZWtzIGxlaWFuIGvDtWlrIGvDvGhtdWQsIG1pcyB2YXN0YXZhZCBrcml0ZWVyaXVtaXRlbGUKYGBge3J9CmNhX2ludGVyZXN0aW5nX3BlYWtzID0gY2Fbd2hpY2goY2EkVjggJWluJSBjYV9zcGxpY2luZyRWMSksXQppbnRlcmVzdGluZ19wZWFrcyA9IGRwbHlyOjpzZWxlY3QoY2FfaW50ZXJlc3RpbmdfcGVha3MsIGMoIlYxIiwgIlYyIiwgIlYzIiwgIlY0IiwgIlY4IiwgIlY5IiwgIlYxMCIsICJWMTciLCJWMTkiKSkKY29sbmFtZXMoaW50ZXJlc3RpbmdfcGVha3MpID0gYygicGVha19pZCIsInBlYWtfY2hyIiwgInBlYWtfc3RhcnQiLCAicGVha19lbmQiLCAicGVha19zbnBpZCIsICJwZWFrX3NucF9jaHIiLCAicGVha19zbnBfcG9zIiwgInBlYWtfc2xvcGUiLCAiY2FfcHZhbHVlIikKaW50ZXJlc3RpbmdfcGVha3MKYGBgCgoKR2VlbmlkLCBtaWxsZSBzcGxhaXNzaW1pbmUgb24gUjIgc2VvdHVkIGtyb21hdGlpbmkgYXZhdHVzZWdhCmBgYHtyfQppbnRlcmVzdGluZ19nZW5lcyA9IHNwbGljaW5nW3doaWNoKHNwbGljaW5nJFYxMCAlaW4lIGNhX3NwbGljaW5nJFY0KSxjKCJWMSIsICJWMiIsICJWMyIsIlY0IiwiVjEwIiwiVjEyIiwiVjE5IiwiVjIxIildCmNvbG5hbWVzKGludGVyZXN0aW5nX2dlbmVzKSA9IGMoImdlbmVfaWQiLCAiZ2VuZV9jaHIiLCJnZW5lX3N0YXJ0IiwiZ2VuZV9lbmQiLCJnZW5lX3NucGlkIiwgImdlbmVfc25wX3BvcyIsImdlbmVfc2xvcGUiLCJnZW5lX3B2YWx1ZSIpCmludGVyZXN0aW5nX2dlbmVzCmBgYAoKYGBge3J9CmhlYWQoY2Ffc3BsaWNpbmcpCmBgYAoKCgpTZW9uIGtyb21hdGlpbmkga8O8aG11ZCBqYSBnZWVuaWQKYGBge3J9CmludGVyZXN0aW5nID0gZHBseXI6OmxlZnRfam9pbihpbnRlcmVzdGluZ19nZW5lcywgY2Ffc3BsaWNpbmcsIGJ5ID0gYygiZ2VuZV9zbnBpZCI9IlY0IikpWzE6OV0gJT4lIGxlZnRfam9pbihpbnRlcmVzdGluZ19wZWFrcywgLiwgYnk9YygncGVha19zbnBpZCc9J1YxJykpCmludGVyZXN0aW5nID0gZHBseXI6OnNlbGVjdChpbnRlcmVzdGluZywgLW9uZV9vZignY3RjZl9jaHInLCdnZW5lX2NocicsICdwZWFrX3NucF9jaHInKSkKaW50ZXJlc3RpbmckZ2VuZV9pZCA9IHN1YnN0cihpbnRlcmVzdGluZyRnZW5lX2lkLCAxLCBuY2hhcigiRU5TRzAwMDAwMTcxNzM1LmNvbnRhaW5lZCIpLTEwKQppbnRlcmVzdGluZwpgYGAKCmBgYHtyfQp3cml0ZS50YWJsZShpbnRlcmVzdGluZywgZmlsZSA9IHBhc3RlMChwYXRoLCAnaW50ZXJlc3RpbmcudHh0JyksIGNvbC5uYW1lcyA9IFQsIHF1b3RlID0gRiwgcm93Lm5hbWVzID0gRiwgYXBwZW5kID0gRikKYGBgCgpgYGB7cn0KaW50ZXJlc3RpbmcgPSByZWFkLnRhYmxlKHBhc3RlMChwYXRoLCAnaW50ZXJlc3RpbmcudHh0JyksIGhlYWRlciA9IFRSVUUpCmBgYAoKYGBge3J9CmZpbHRlcmVkID0gaW50ZXJlc3Rpbmdbd2hpY2goYWJzKGludGVyZXN0aW5nJHBlYWtfc2xvcGUpPjAuNCAmIGFicyhpbnRlcmVzdGluZyRnZW5lX3Nsb3BlKT4wLjQgJiBpbnRlcmVzdGluZyRjYV9wdmFsdWU8MWUtNCAmIGludGVyZXN0aW5nJGdlbmVfcHZhbHVlPDFlLTQpLF0KZmlsdGVyZWQKYGBgCgoKIyBBVEFDCmBgYHtyfQojcHJvb3ZpZApBVEFDX3NhbXBsZV9tZXRhZGF0YSA9IHJlYWQudGFibGUocGFzdGUwKHBhdGgsJ1FDX21lYXN1cmVzL3J1bl9zYW1wbGVfYWNjZXNzaW9uX1BoYXNlSUlJLnR4dCcpKQpjb2xuYW1lcyhBVEFDX3NhbXBsZV9tZXRhZGF0YSkgPSBjKCJzYW1wbGVfaWQiLCAiZ2Vub3R5cGVfaWQiKQpBVEFDX3NhbXBsZV9tZXRhZGF0YVsiY29uZGl0aW9uX25hbWUiXSA9IHJlcCgibmFpdmUiLCBkaW0oQVRBQ19zYW1wbGVfbWV0YWRhdGEpWzFdKQpgYGAKCmBgYHtyfQojZ2Vub3TDvMO8YmlkCnZjZl9maWxlID0gcmVhZFJEUyhwYXN0ZTAocGF0aCwgJ2dlbm90eXBlcy9LdW1hc2FrYV8xMDBfc2FtcGxlcy5tZXJnZWQucmRzJykpCmBgYAoKYGBge3J9CkFUQUNfbWV0YV9kZiA9IHJlYWQudGFibGUocGFzdGUwKHBhdGgsICdBVEFDX21ldGFfZGYnKSwgaGVhZGVyID0gVFJVRSkKQVRBQ19wZWFrX21ldGFkYXRhID0gcmVhZC50YWJsZShwYXN0ZTAocGF0aCwnQVRBQ19wZWFrX21ldGFkYXRhJyksIGhlYWRlciA9IFRSVUUpCmBgYAoKCmBgYHtyfQpyZWdpb25zX2RmID0gdW5pcXVlKGZpbHRlcmVkWyxjKCdwZWFrX2lkJywgJ3BlYWtfY2hyJywncGVha19zdGFydCcsICdwZWFrX2VuZCcsJ3BlYWtfc25waWQnLCdnZW5lX2lkJywgJ3BlYWtfY2hyJywnZ2VuZV9zdGFydCcsICdnZW5lX2VuZCcsJ2dlbmVfc25waWQnLCdnZW5lX3NucF9wb3MnKV0pCmNvbG5hbWVzKHJlZ2lvbnNfZGYpID0gYygncGVha19pZCcsICdwZWFrX2NocicsICdwZWFrX3N0YXJ0JywgJ3BlYWtfZW5kJywgJ3BlYWtfcnNfaWQnLCAnZ2VuZV9pZCcsICdnZW5lX2NocicsICdnZW5lX3N0YXJ0JywgJ2dlbmVfZW5kJywgJ2dlbmVfcnNfaWQnLCAnZ2VuZV9wb3MnKQpyZWdpb25zX2RmCmBgYAoKCmBgYHtyfQojcm0odmNmX2ZpbGUsQVRBQ19jb3VudHMpCmBgYAoKIyBSTkEKYGBge3J9ClJOQV9zYW1wbGVfbWV0YWRhdGEgPSByZWFkLnRhYmxlKCIvZ3Bmcy9ocGNob21lL2E3MjA5NC9ocGMvZGF0YXNldHMvY29udHJvbGxlZF9hY2Nlc3MvU2FtcGxlQXJjaGVvbG9neS9zdHVkaWVzL2NsZWFuZWQvR0VVVkFESVMudHN2IiwgaGVhZGVyID0gVFJVRSlbLGMoInNhbXBsZV9pZCIsImdlbm90eXBlX2lkIiwiY29uZGl0aW9uIildCmNvbG5hbWVzKFJOQV9zYW1wbGVfbWV0YWRhdGEpWzNdID0gImNvbmRpdGlvbl9uYW1lIgpgYGAKCmBgYHtyfQppZiAoRkFMU0UpewogICMgUk5BIHNlcSBsdWdlbWl0ZSBhcnYgdXNlZCBmb3IgY2FsY3VsYXRpbmcgbGlicmFyeSBzaXplCiAgUk5BX2NvdW50cyA9IHJlYWQudGFibGUoIi9ncGZzL2hwY2hvbWUvYTcyMDk0L2hwYy9wcm9qZWN0cy9STkFzZXFfcGlwZWxpbmUvcmVzdWx0cy9leHByZXNzaW9uX21hdHJpY2VzL2ZlYXR1cmVDb3VudHMvR0VVVkFESVMudHN2Lmd6IiwgaGVhZGVyID0gVFJVRSkKICBSTkFfbWV0YV9kZiA9IHdpZ2dsZXBsb3RyQ29uc3RydWN0TWV0YWRhdGEoUk5BX2NvdW50cywgUk5BX3NhbXBsZV9tZXRhZGF0YSwgIi9ncGZzL2hwYy9ob21lL2E3MjA5NC9wcm9qZWN0cy9STkFzZXFfcGlwZWxpbmUvcHJvY2Vzc2VkL0dFVVZBRElTL2JpZ3dpZyIsIGJpZ1dpZ19zdWZmaXggPSAiLnN0cjEuYnciLCBjb25kaXRpb25fbmFtZV9sZXZlbHMgPSBjKCJuYWl2ZSIpKQogIHJtKFJOQV9jb3VudHMpCiAgc2F2ZVJEUyhSTkFfbWV0YV9kZiwgcGFzdGUwKHBhdGgsICdSTkFfbWV0YV9kZicpKQp9CmBgYAoKYGBge3J9ClJOQV9tZXRhX2RmID0gcmVhZFJEUyhwYXN0ZTAocGF0aCwgJ1JOQV9tZXRhX2RmJykpClJOQV9tZXRhX2RmCmBgYAoKCmBgYHtyfQpyZWdpb25zX2RmID0gdW5pcXVlKGZpbHRlcmVkWyxjKCdnZW5lX2lkJywgJ3BlYWtfY2hyJywnZ2VuZV9zdGFydCcsICdnZW5lX2VuZCcsJ2dlbmVfc25waWQnLCdnZW5lX3NucF9wb3MnKV0pCmNvbG5hbWVzKHJlZ2lvbnNfZGYpID0gYygnZ2VuZV9pZCcsICdjaHInLCAnc3RhcnQnLCAnZW5kJywgJ3JzX2lkJywgJ3BvcycpCnJlZ2lvbnNfZGYKYGBgCgpnZWVuaWRlIGFubm90YXRzaW9vbmlkIGphIHRyYW5za3JpcHRpZGUgYW5ub3RhdHNpb29uaWQKYGBge3J9CmlmIChGQUxTRSl7CiAgZ3RmX2RmIDwtIGFzLmRhdGEuZnJhbWUocnRyYWNrbGF5ZXI6OmltcG9ydChwYXN0ZTAocGF0aCwgJ2dlbm90eXBlcy9Ib21vX3NhcGllbnMuR1JDaDM4Ljk2LmNoci5ndGYuZ3onKSkpCiAgZmlsdGVyZWRfYW5ub3RhdGlvbnMgPSBndGZfZGZbZ3RmX2RmJGdlbmVfaWQgJWluJSByZWdpb25zX2RmJGdlbmVfaWQsXQogIGZpbHRlcmVkX2Fubm90YXRpb25zCiAgcm0oZ3RmX2RmKQogIHNhdmVSRFMoZmlsdGVyZWRfYW5ub3RhdGlvbnMsIHBhc3RlMChwYXRoLCAnZmlsdGVyZWRfYW5ub3RhdGlvbnMnKSkKfQpgYGAKCgpgYGB7cn0KZmlsdGVyZWRfYW5ub3RhdGlvbnMgPSByZWFkUkRTKHBhc3RlMChwYXRoLCAnZmlsdGVyZWRfYW5ub3RhdGlvbnMnKSkKZmlsdGVyZWRfYW5ub3RhdGlvbnMKYGBgCgoKS29payBnZWVuaSBla3NvbmlkIEdSYW5nZXMgb2JqZWt0aWRlbmEKYGBge3J9CmZpbmRfcGVha19hbm5vdGF0aW9ucyA9IGZ1bmN0aW9uKHJlZ2lvbl9jb29yZHMsIGNociwgUk5BX3BlYWtfbWV0YWRhdGEpewogIFJOQV9wZWFrX2Fubm90ID0gd2lnZ2xlcGxvdHJFeHRyYWN0UGVha3MocmVnaW9uX2Nvb3JkcywgY2hyb20gPSBjaHIsIFJOQV9wZWFrX21ldGFkYXRhKQogIFJOQV9wZWFrX2Fubm90JHBlYWtfYW5ub3QkdHJhbnNjcmlwdF9pZD0nUk5BJwogIFJOQV9wZWFrX2Fubm90JHBlYWtfYW5ub3QkZ2VuZV9pZCA9ICdSTkEnCiAgUk5BX3BlYWtfYW5ub3QkcGVha19hbm5vdCRnZW5lX25hbWUgPSAnUk5BLXNlcScKICBuYW1lcyhSTkFfcGVha19hbm5vdCRwZWFrX2xpc3QpID0gJ1JOQScKICByZXR1cm4oUk5BX3BlYWtfYW5ub3QpCn0KYGBgCgpMZWlhbiB2Y2YgZmFpbGlzdCBsb2lndSwgbWlzIHZhc3RhYiB1dXJpdGF2YWxlIGdlZW5pbGUKYGBge3J9CmZpbmRfZ2Vub3R5cGUgPSBmdW5jdGlvbihnZW5lX2lkLCByZWdpb25fY29vcmRzKXsKICBsaWJyYXJ5KEdlbm9taWNSYW5nZXMpCiAgZ2VuZV9yYW5nZSA9IEdSYW5nZXMoc2VxbmFtZXMgPWZpbHRlcmVkX2Fubm90YXRpb25zW3doaWNoKGZpbHRlcmVkX2Fubm90YXRpb25zJHR5cGU9PSdnZW5lJyAmIGZpbHRlcmVkX2Fubm90YXRpb25zJGdlbmVfaWQgPT1nZW5lX2lkKSwnc2VxbmFtZXMnXSwgc3RyYW5kID0gYygiKiIpLCByYW5nZXMgPSBJUmFuZ2VzKHN0YXJ0ID0gcmVnaW9uX2Nvb3Jkc1sxXSwgZW5kID0gcmVnaW9uX2Nvb3Jkc1syXSwgbmFtZXMgPSBnZW5lX2lkKSkKICB2Y2ZfZmlsZSA9IHBhc3RlMChwYXRoLCAnZ2Vub3R5cGVzL0dFVVZBRElTX0dSQ2gzOF9maWx0ZXJlZC52Y2YuZ3onKQogIGdlbm90eXBlID0gc2NhblRhYml4RGF0YUZyYW1lKHZjZl9maWxlLCBnZW5lX3JhbmdlLCBjb2xfbmFtZXMgPSBGQUxTRSlbWzFdXQogICNzYXZlUkRTKGdlbm90eXBlLCBwYXN0ZTAocGF0aCwgJ2dlbm90eXBlJykpCiAgCiAgI3pncmVwIC1tIDEgIiNDSFJPTSIgR0VVVkFESVNfR1JDaDM4X2ZpbHRlcmVkLnZjZi5neiA+IHZjZl9nZW5vdHlwZV9pZAogICN2aW0gdmNmX2dlbm90eXBlX2lkIGRlbGV0ZSAjCiAgCiAgdiA9IHNjYW4ocGFzdGUwKHBhdGgsICcvZ2Vub3R5cGVzL3ZjZl9nZW5vdHlwZV9pZCcpLCBjaGFyYWN0ZXIoKSwgcXVvdGUgPSAiIikKICAjdW5saW5rKHBhc3RlMChwYXRoLCAnL2dlbm90eXBlcy92Y2ZfZ2Vub3R5cGVfaWQnKSkKICBjb2xuYW1lcyhnZW5vdHlwZSkgPSB2CiAgCiAgZ2Vub3R5cGVbZ2Vub3R5cGU9PSIwfDAiXTwtMAogIGdlbm90eXBlW2dlbm90eXBlPT0iMXwwIl08LTEKICBnZW5vdHlwZVtnZW5vdHlwZT09IjB8MSJdPC0xCiAgZ2Vub3R5cGVbZ2Vub3R5cGU9PSIxfDEiXTwtMgogIAogIHJldHVybihnZW5vdHlwZSkKfQpgYGAKCgpgYGB7cn0KZmluZF90cmFja19kYXRhID0gZnVuY3Rpb24oZ2Vub3R5cGUsIGNociwgUk5BX21ldGFfZGYpewogICMgYWRkIGNvbG91ciBncm91cAogIGNvbG91cl9ncm91cCA9IGdlbm90eXBlW3doaWNoKGdlbm90eXBlJENIUk9NPT1jaHIgJiBnZW5vdHlwZSRQT1M9PXBvcyksIF0gJT4lIHNlbGVjdCgxMDo0NTQpICU+JSBnYXRoZXIoLiwga2V5PSBjb2xuYW1lcyguKSwgdmFsdWU9LlsxLF0pCiAgY29sbmFtZXMoY29sb3VyX2dyb3VwKSA9IGMoJ2dlbm90eXBlX2lkJywgJ2NvbG91cl9ncm91cCcpCiAgCiAgUk5BX3RyYWNrX2RhdGEgPSBkcGx5cjo6bGVmdF9qb2luKFJOQV9tZXRhX2RmLCBjb2xvdXJfZ3JvdXAsIGJ5PSdnZW5vdHlwZV9pZCcpICU+JSBkcGx5cjo6bXV0YXRlKHRyYWNrX2lkID0gIlJOQS1zZXEiKQogIFJOQV90cmFja19kYXRhWywgJ2NvbG91cl9ncm91cCddID0gYXMuZmFjdG9yKFJOQV90cmFja19kYXRhWywgJ2NvbG91cl9ncm91cCddKQogIHJldHVybihSTkFfdHJhY2tfZGF0YSkKfQpgYGAKCgpBVEFDIGpvb25pc2VkCmBgYHtyfQpqb2ludF9wbG90bGlzdCA9IGxpc3QoKQoKZm9yIChpIGluIDE6ZGltKHJlZ2lvbnNfZGYpWzFdKXsKICBBVEFDX3JzX2lkID0gcmVnaW9uc19kZltpLCAncGVha19yc19pZCddCiAgQVRBQ19yZWdpb25fY29vcmRzPWMocmVnaW9uc19kZltpLCdwZWFrX3N0YXJ0J10tMTAwMCwgcmVnaW9uc19kZltpLCdwZWFrX2VuZCddKzEwMDApCiAgY2hyID0gcmVnaW9uc19kZltpLCdwZWFrX2NociddCiAgQVRBQ19wZWFrX2Fubm90ID0gd2lnZ2xlcGxvdHJFeHRyYWN0UGVha3MocmVnaW9uX2Nvb3JkcywgY2hyb20gPSBjaHIsIEFUQUNfcGVha19tZXRhZGF0YSkKICAKICAjIGFkZCBjb2xvdXIgZ3JvdXAKICBBVEFDX2NvbG91cl9ncm91cCA9IGRhdGEuZnJhbWUoZ2Vub3R5cGVfaWQgPSBuYW1lcyh2Y2ZfZmlsZSRnZW5vdHlwZXNbQVRBQ19yc19pZCxdKSwgY29sb3VyX2dyb3VwPXZjZl9maWxlJGdlbm90eXBlc1tyc19pZCxdKQogIEFUQUNfdHJhY2tfZGF0YSA9IGRwbHlyOjpsZWZ0X2pvaW4oQVRBQ19tZXRhX2RmLCBBVEFDX2NvbG91cl9ncm91cCwgYnk9J2dlbm90eXBlX2lkJykgJT4lIGRwbHlyOjptdXRhdGUodHJhY2tfaWQgPSAiQVRBQy1zZXEiKQogIEFUQUNfdHJhY2tfZGF0YVssICdjb2xvdXJfZ3JvdXAnXSA9IGFzLmZhY3RvcihBVEFDX3RyYWNrX2RhdGFbLCAnY29sb3VyX2dyb3VwJ10pCiAgCiAgQVRBQ19jb3ZlcmFnZSA9IHBsb3RDb3ZlcmFnZShleG9ucyA9IEFUQUNfcGVha19hbm5vdCRwZWFrX2xpc3QsIGNkc3MgPSBBVEFDX3BlYWtfYW5ub3QkcGVha19saXN0LCB0cmFja19kYXRhID0gQVRBQ190cmFja19kYXRhLCByZXNjYWxlX2ludHJvbnMgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNjcmlwdF9hbm5vdGF0aW9ucyA9IEFUQUNfcGVha19hbm5vdCRwZWFrX2Fubm90LCBmaWxsX3BhbGV0dGUgPSBnZXRHZW5vdHlwZVBhbGV0dGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0X2V4b25zID0gRkFMU0UsIHRyYW5zY3JpcHRfbGFiZWwgPSBGQUxTRSwgcGxvdF9mcmFjdGlvbiA9IDAuMSwgaGVpZ2h0cyA9IGMoMC43LDAuMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbl9jb29yZHMgPSBBVEFDX3JlZ2lvbl9jb29yZHMsIHJldHVybl9zdWJwbG90c19saXN0ID0gVFJVRSwgY292ZXJhZ2VfdHlwZSA9ICJsaW5lIikKICAKICAKICBqb2ludF9wbG90ID0gY293cGxvdDo6cGxvdF9ncmlkKEFUQUNfY292ZXJhZ2UkY292ZXJhZ2VfcGxvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRBQ19jb3ZlcmFnZSR0eF9zdHJ1Y3R1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMywyKSkKICAKICBqb2ludF9wbG90bGlzdFtbaV1dID0gam9pbnRfcGxvdAogIHByaW50KGpvaW50X3Bsb3QpCiAgZ2dzYXZlKHBhc3RlMCgnL2dwZnMvaHBjaG9tZS9ldmVsaW45NS9wbG90cy9jYV9zcGxpY2luZy8nLHJlZ2lvbnNfZGZbaSwncGVha19pZCddLCcucGRmJykpCiAgCn0KYGBgCgpSTkEgam9vbmlzZWQKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKUk5BX2pvaW50X3Bsb3RsaXN0ID0gbGlzdCgpCmZvciAoaSBpbiAxOmRpbShyZWdpb25zX2RmKVsxXSl7CiAgZ2VuZV9yc19pZCA9IHJlZ2lvbnNfZGZbaSwgJ2dlbmVfcnNfaWQnXQogIHBvcyA9IHJlZ2lvbnNfZGZbaSwgJ2dlbmVfcG9zJ10KICBnZW5lX2lkID0gcmVnaW9uc19kZltpLCAnZ2VuZV9pZCddCiAgZ2VuZV9yZWdpb25fY29vcmRzID0gYyhmaWx0ZXJlZF9hbm5vdGF0aW9uc1t3aGljaChmaWx0ZXJlZF9hbm5vdGF0aW9ucyR0eXBlPT0nZ2VuZScgJiBmaWx0ZXJlZF9hbm5vdGF0aW9ucyRnZW5lX2lkID09Z2VuZV9pZCksJ3N0YXJ0J10sIGZpbHRlcmVkX2Fubm90YXRpb25zW3doaWNoKGZpbHRlcmVkX2Fubm90YXRpb25zJHR5cGU9PSdnZW5lJyAmIGZpbHRlcmVkX2Fubm90YXRpb25zJGdlbmVfaWQgPT1nZW5lX2lkKSwnZ2VuZV9lbmQnXSkKICBjaHIgPSByZWdpb25zX2RmW2ksJ2dlbmVfY2hyJ10KICAKICBSTkFfcGVha19tZXRhZGF0YSA9IGZpbHRlcmVkX2Fubm90YXRpb25zW3doaWNoKGZpbHRlcmVkX2Fubm90YXRpb25zJHR5cGU9PSdleG9uJyAmIGZpbHRlcmVkX2Fubm90YXRpb25zJGdlbmVfaWQ9PWdlbmVfaWQpLGMoInNlcW5hbWVzIiwgInN0YXJ0IiwgImVuZCIsICJzdHJhbmQiKV0KICBjb2xuYW1lcyhSTkFfcGVha19tZXRhZGF0YSlbMV09J2NocicKICAKICBnZW5vdHlwZT1maW5kX2dlbm90eXBlKGdlbmVfaWQsIGdlbmVfcmVnaW9uX2Nvb3JkcykKICAKICBSTkFfcGVha19hbm5vdCA9IGZpbmRfcGVha19hbm5vdGF0aW9ucyhnZW5lX3JlZ2lvbl9jb29yZHMsIGNociwgUk5BX3BlYWtfbWV0YWRhdGEpCiAgUk5BX3RyYWNrX2RhdGEgPSBmaW5kX3RyYWNrX2RhdGEoZ2Vub3R5cGUsIGNociwgUk5BX21ldGFfZGYpCiAgCiAgaWYgKHN1bShpcy5uYShSTkFfdHJhY2tfZGF0YSRjb2xvdXJfZ3JvdXApKTwxMDApewogIFJOQV9jb3ZlcmFnZSA9IHBsb3RDb3ZlcmFnZShleG9ucyA9IFJOQV9wZWFrX2Fubm90JHBlYWtfbGlzdCwgY2RzcyA9IFJOQV9wZWFrX2Fubm90JHBlYWtfbGlzdCwgdHJhY2tfZGF0YSA9IFJOQV90cmFja19kYXRhLCByZXNjYWxlX2ludHJvbnMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2NyaXB0X2Fubm90YXRpb25zID0gUk5BX3BlYWtfYW5ub3QkcGVha19hbm5vdCwgZmlsbF9wYWxldHRlID0gZ2V0R2Vub3R5cGVQYWxldHRlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdF9leG9ucyA9IEZBTFNFLCB0cmFuc2NyaXB0X2xhYmVsID0gRkFMU0UsIHBsb3RfZnJhY3Rpb24gPSAwLjEsIGhlaWdodHMgPSBjKDAuNywwLjMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpb25fY29vcmRzID0gcmVnaW9uX2Nvb3JkcywgcmV0dXJuX3N1YnBsb3RzX2xpc3QgPSBUUlVFLCBjb3ZlcmFnZV90eXBlID0gImxpbmUiKQogIAogIAogIGpvaW50X3Bsb3QgPSBjb3dwbG90OjpwbG90X2dyaWQoUk5BX2NvdmVyYWdlJGNvdmVyYWdlX3Bsb3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJOQV9jb3ZlcmFnZSR0eF9zdHJ1Y3R1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMywyKSkKCiAgUk5BX2pvaW50X3Bsb3RsaXN0W1tpXV0gPSBqb2ludF9wbG90CiAgcHJpbnQoam9pbnRfcGxvdCkKICBnZ3NhdmUocGFzdGUwKCcvZ3Bmcy9ocGNob21lL2V2ZWxpbjk1L3Bsb3RzL2NhX3NwbGljaW5nLycsZ2VuZV9pZCwnLnBkZicpKSAgCiAgfQp9CmBgYAoKCgo=